﻿#region << 文件说明 >>

/*----------------------------------------------------------------
 * 命名空间：Vampirewal.Admin.ApprovalFlowEngine
 * 唯一标识：3b62464a-98da-47a0-a071-90a7ef94803b
 * 文件名：ApprovalFlowManager
 *
 * 创建者：杨程
 * 电子邮箱：235160615@qq.com
 * 创建时间：2024/8/14 15:23:28
 * 版本：V1.0.0
 * 描述：
 *
 * ----------------------------------------------------------------
 * 修改人：
 * 时间：
 * 修改说明：
 *
 * 版本：V1.0.1
 *----------------------------------------------------------------*/

#endregion << 文件说明 >>

namespace Vampirewal.Admin.ApprovalFlowEngine;

/// <summary>
///
/// </summary>
public class ApprovalFlowManager
{
    /// <summary>
    /// 构造函数
    /// </summary>
    public ApprovalFlowManager()
    {
        UserSelectorDic = new Dictionary<string, IUserSelector>();
        ConditionSelectorDic = new Dictionary<string, IConditionSelector>();
        ApprovalFlowBaseDic = new Dictionary<string, ApprovalFlowBase>();

        Register();
    }

    /// <summary>
    /// 注册用户选择器和条件选择器
    /// </summary>
    private void Register()
    {
        var types = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes()).Where(t => t == typeof(IUserSelector) || t == typeof(IConditionSelector) || t.IsSubclassOf(typeof(ApprovalFlowBase))).ToArray();

        foreach (var v in types)
        {
            if (v.GetInterface("IUserSelector") == typeof(IUserSelector))
            {
                var attr = v.GetCustomAttribute<UserSelecorAttribute>();

                if (attr != null)
                {
                    var obj = (Activator.CreateInstance(v) as IUserSelector)!;

                    UserSelectorDic.Add(attr.Key, obj);
                }
            }
            else if (v.GetInterface("IConditionSelector") == typeof(IConditionSelector))
            {
                var attr = v.GetCustomAttribute<ConditionSelectorAttribute>();

                if (attr != null)
                {
                    var obj = (Activator.CreateInstance(v) as IConditionSelector)!;

                    ConditionSelectorDic.Add(attr.Key, obj);
                }
            }
            else if (v.BaseType == typeof(ApprovalFlowBase))
            {
                var obj = (Activator.CreateInstance(v) as ApprovalFlowBase)!;

                obj._ApprovalFlowManager = this;

                obj.FlowNodes = new List<FlowNode>();
                obj.FlowLines = new List<FlowLine>();
                obj.FlowParams = new List<string>();

                var flowParamsAttr = v.GetCustomAttributes<FlowParamAttribute>();

                foreach (var attr in flowParamsAttr)
                {
                    obj.FlowParams.Add(attr.ParamName);
                }

                obj.AddFlowNode();
                obj.AddFlowLine();

                ApprovalFlowBaseDic.Add(obj.FlowCode, obj);
            }
        }
    }

    #region [     审批流程配置     ]

    /// <summary>
    /// 流程flow配置字典
    /// </summary>
    internal Dictionary<string, ApprovalFlowBase> ApprovalFlowBaseDic { get; set; }

    /// <summary>
    /// 获取审批流程配置
    /// </summary>
    /// <param name="flowCode"></param>
    /// <returns></returns>
    internal ApprovalFlowBase? GetWorkFlow(string flowCode)
    {
        if (ApprovalFlowBaseDic.TryGetValue(flowCode, out var ApprovalFlow))
        {
            return ApprovalFlow;
        }

        return null;
    }

    #endregion

    #region [     用户选择器     ]

    /// <summary>
    /// 用户选择器Type字典
    /// </summary>
    internal Dictionary<string, IUserSelector> UserSelectorDic { get; set; }

    /// <summary>
    /// 获取用户选择器
    /// </summary>
    /// <param name="key"></param>
    /// <returns></returns>
    internal IUserSelector? GetUserSelecor(string key)
    {
        if (UserSelectorDic.TryGetValue(key, out var selector))
        {
            return selector;
        }

        return null;
    }

    #endregion

    #region [     条件选择器     ]

    /// <summary>
    /// 条件选择器Type字典
    /// </summary>
    internal Dictionary<string, IConditionSelector> ConditionSelectorDic { get; set; }

    /// <summary>
    /// 获取条件选择器
    /// </summary>
    /// <param name="key"></param>
    /// <returns></returns>
    internal IConditionSelector? GetConditionSelector(string key)
    {
        if (ConditionSelectorDic.TryGetValue(key, out var selector))
        {
            return selector;
        }

        return null;
    }

    #endregion
}